<?php
/**
 * Created by PhpStorm.
 * User: sosyuki
 * Date: 2019-01-14
 * Time: 10:30
 */

namespace Drupal\shushengyuan\Traits;


trait ServicesCommerceAddOrderTrait {

  protected function commerceOrderProductAddPid($order, $product_id, $quantity, $price, int $type = 0) {
    if ($product = commerce_product_load($product_id)) {
      if ($price === NULL) {
        $productWrapper = entity_metadata_wrapper('commerce_product', $product);
        $price = $productWrapper->commerce_price->amount->value();
      }
      $line_item = commerce_product_line_item_new($product, $quantity);
      return $this->commerceOrderProductAdd($order, $line_item, $price, $type);
    }
    return FALSE;
  }

  protected function commerceOrderProductAdd($order, $line_item, int $price, int $type) {
    //    watchdog(__LINE__, serialize($price));
    $combine = TRUE;
    $line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
    $line_item_wrapper->field_standard_type->set($type);
    $line_item_wrapper->save();
    if (is_null($line_item_wrapper->commerce_unit_price->value())) {
      return FALSE;
    }
    $line_item->order_id = $order->order_id;
    $order_wrapper = entity_metadata_wrapper('commerce_order', $order);
    $product = $line_item_wrapper->commerce_product->value();
    $quantity = $line_item->quantity;
    rules_invoke_all('commerce_cart_product_prepare', $order, $product, $quantity);
    $matching_line_item = NULL;
    if ($combine) {
      $comparison_properties = ['type', 'commerce_product'];
      foreach (field_info_instances('commerce_line_item', $line_item->type) as $info) {
        if (!empty($info['commerce_cart_settings']['field_access'])) {
          $comparison_properties[] = $info['field_name'];
        }
      }
      $clone_line_item = clone($line_item);
      drupal_alter('commerce_cart_product_comparison_properties', $comparison_properties, $clone_line_item);
      foreach ($order_wrapper->commerce_line_items as $delta => $matching_line_item_wrapper) {
        foreach ($comparison_properties as $property) {
          if (
            !isset($matching_line_item_wrapper->value()->{$property})
            && !isset($line_item_wrapper->value()->{$property})
          ) {
            continue;
          }
          if (
            (!isset($matching_line_item_wrapper->value()->{$property})
              && isset($line_item_wrapper->value()->{$property}))
            ||
            (isset($matching_line_item_wrapper->value()->{$property})
              && !isset($line_item_wrapper->value()->{$property}))
            ||
            $matching_line_item_wrapper->{$property}->raw() != $line_item_wrapper->{$property}->raw()
          ) {
            // Continue the loop with the next line item.
            continue 2;
          }
        }
        $matching_line_item = $matching_line_item_wrapper->value();
        break;
      }
    }
    //    watchdog(__LINE__, serialize($matching_line_item));
    if (empty($matching_line_item)) {
      $line_item->commerce_unit_price[LANGUAGE_NONE]['0']['amount'] = $price;
      $line_item->commerce_unit_price[LANGUAGE_NONE]['0']['data']['components']['0']['price']['amount'] = $price;
      commerce_line_item_save($line_item);
      $order_wrapper->commerce_line_items[] = $line_item;
    }
    else {
      $matching_line_item->quantity += $quantity;
      $matching_line_item->data = array_merge($line_item->data, $matching_line_item->data);
      if ($price === NULL) {
        $price = $line_item->commerce_unit_price[LANGUAGE_NONE]['0']['amount'];
      }
      //      watchdog(__LINE__, serialize($price));
      $matching_line_item->commerce_unit_price[LANGUAGE_NONE]['0']['amount'] = $price;
      $matching_line_item->commerce_unit_price[LANGUAGE_NONE]['0']['data']['components']['0']['price']['amount'] = $price;
      commerce_line_item_save($matching_line_item);
      $line_item = $matching_line_item;
    }

    $line_item_wrapper = entity_metadata_wrapper('commerce_line_item', $line_item);
    $line_item_wrapper->field_standard_type->set($type);
    $line_item_wrapper->save();

    // Save the updated order.
    commerce_order_save($order);

    // Invoke the product add event with the newly saved or updated line item.
    rules_invoke_all('commerce_cart_product_add', $order, $product, $quantity, $line_item);
    //    watchdog(__LINE__, serialize($line_item));
    // Return the line item.
    return $line_item;
  }
}
